﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Data.SQLite;

namespace dogd.WalkingSkeleton
{
	class Program
	{
		static void Main(string[] args)
		{
			string sql = ScriptReader.ReadFromResource(typeof(Band).Assembly, 
														"dogd.WalkingSkeleton.Schema.sql");

			//Repository inMemoryRepo = new Repository(new InMemorySqliteConnectionProvider(), 
			//    new MetadataProvider(), 
			//    new SqliteParameterFactory());

			//inMemoryRepo.CreateNewRepository(sql);
			//Test(inMemoryRepo);

			const string testDb = "TestDb.db";
			if (!System.IO.File.Exists(testDb))
			{
				System.IO.File.Delete(testDb);
			}

			Repository fileRepo = new Repository(
				new SqliteConnectionProvider(testDb), 
				new MetadataProvider(), 
				new SqliteParameterFactory());

			fileRepo.CreateNewRepository(sql);
			Test(fileRepo);

			System.Console.ReadKey();
		}

		private static void Test(Repository repo)
		{
			var rem = new Band("REM");
			var floyd = new Band("Pink Floyd");

			Stopwatch watch = new Stopwatch();
			watch.Start();

			repo.Add<Band>(rem);
			repo.Add<Band>(floyd);

			// info stolen from wikipedia
			// rem albums
			repo.Add<Album>(new Album("Murmur", 1983, rem));
			repo.Add<Album>(new Album("Reckoning", 1984, rem));
			repo.Add<Album>(new Album("Fables of the Reconstruction", 1985, rem));
			repo.Add<Album>(new Album("Lifes Rich Pageant", 1986, rem));
			repo.Add<Album>(new Album("Document", 1987, rem));
			repo.Add<Album>(new Album("Green", 1988, rem));
			repo.Add<Album>(new Album("Out of Time", 1991, rem));
			repo.Add<Album>(new Album("Automatic for the People", 1992, rem));
			repo.Add<Album>(new Album("Monster", 1994, rem));
			repo.Add<Album>(new Album("New Adventures in Hi-Fi", 1996, rem));
			repo.Add<Album>(new Album("Up", 1998, rem));
			repo.Add<Album>(new Album("Reveal", 2001, rem));
			repo.Add<Album>(new Album("Around the Sun", 2004, rem));
			repo.Add<Album>(new Album("Accelerate", 2008, rem));
			repo.Add<Album>(new Album("Collapse into Now", 2011, rem));

			//pink floyd albums
			repo.Add<Album>(new Album("The Piper at the Gates of Dawn", 1967, floyd));
			repo.Add<Album>(new Album("A Saucerful of Secrets", 1968, floyd));
			repo.Add<Album>(new Album("Soundtrack from the Film More", 1969, floyd));
			repo.Add<Album>(new Album("Ummagumma", 1969, floyd));
			repo.Add<Album>(new Album("Atom Heart Mother", 1970, floyd));
			repo.Add<Album>(new Album("Meddle", 1971, floyd));
			repo.Add<Album>(new Album("Obscured by Clouds", 1972, floyd));
			repo.Add<Album>(new Album("The Dark Side of the Moon", 1973, floyd));
			repo.Add<Album>(new Album("Wish You Were Here", 1975, floyd));
			repo.Add<Album>(new Album("Animals", 1977, floyd));
			repo.Add<Album>(new Album("The Wall", 1979, floyd));
			repo.Add<Album>(new Album("The Final Cut", 1983, floyd));
			repo.Add<Album>(new Album("A Momentary Lapse of Reason", 1987, floyd));
			repo.Add<Album>(new Album("The Division Bell", 1994, floyd));

			var remDiscography = repo.ReadAll<Album>(rem.PrimaryKey);

			Console.WriteLine(rem.Name);

			foreach (var album in remDiscography)
			{
				Console.WriteLine(string.Format("{0} : {1}", album.Name, album.Year));
			}

			Console.WriteLine("===============================================");

			var pinkFloydDiscography = repo.ReadAll<Album>(floyd.PrimaryKey);

			Console.WriteLine(floyd.Name);
			foreach (var album in pinkFloydDiscography)
			{
				Console.WriteLine(string.Format("{0} : {1}", album.Name, album.Year));
			}

			Console.WriteLine("===============================================");

			var filters = new FilterByCollection();
			filters.Add(new FilterBy("ReleaseYear", FilterOperator.GreaterThan, 1979));
			filters.Add(new FilterBy("BandID", FilterOperator.Equal, floyd.PrimaryKey));

			var laterAlbums = repo.ReadAll<Album>(filters);

			Console.WriteLine("Pink Floyd Later Albums");
			foreach (var album in laterAlbums)
			{
				Console.WriteLine(string.Format("{0} : {1}", album.Name, album.Year));
			}

			Console.WriteLine("===============================================");

			watch.Stop();

			long milli = watch.ElapsedMilliseconds;

			// multithreaded tests...

			//const int insertions = 100;

			//System.Threading.ThreadPool.QueueUserWorkItem(o =>
			//{
			//    var tmbg = new Band("TMBG");
			//    repo.Add<Band>(tmbg);

			//    for (int i = 0; i < insertions; ++i)
			//    {
			//        string albumName = string.Format("{0} {1}", tmbg.Name, i + 1);
			//        System.Console.WriteLine(albumName);
			//        repo.Add<Album>(new Album(albumName, 1960 + i, tmbg));
			//    }
			//});

			//System.Threading.ThreadPool.QueueUserWorkItem(o =>
			//{
			//    var fz = new Band("Frank Zappa");
			//    repo.Add<Band>(fz);

			//    for (int i = 0; i < insertions; ++i)
			//    {
			//        string albumName = string.Format("{0} {1}", fz.Name, i + 1);
			//        System.Console.WriteLine(albumName);
			//        repo.Add<Album>(new Album(albumName, 1960 + i, fz));
			//    }
			//});

			//System.Threading.ThreadPool.QueueUserWorkItem(o =>
			//{
			//    var heads = new Band("Talking Heads");
			//    repo.Add<Band>(heads);

			//    for (int i = 0; i < insertions; ++i)
			//    {
			//        string albumName = string.Format("{0} {1}", heads.Name, i + 1);
			//        System.Console.WriteLine(albumName);
			//        repo.Add<Album>(new Album(albumName, 1960 + i, heads));
			//    }
			//});

			//System.Threading.ThreadPool.QueueUserWorkItem(o =>
			//{
			//    var house = new Band("Crowded House");
			//    repo.Add<Band>(house);

			//    for (int i = 0; i < insertions; ++i)
			//    {
			//        string albumName = string.Format("{0} {1}", house.Name, i + 1);
			//        System.Console.WriteLine(albumName);
			//        repo.Add<Album>(new Album(albumName, 1960 + i, house));
			//    }
			//});

			//System.Threading.ThreadPool.QueueUserWorkItem(o =>
			//{
			//    var allAlbums = repo.ReadAll<Album>();

			//    foreach (var album in allAlbums)
			//    {
			//        System.Console.WriteLine(album.Name);
			//    }
			//});

			//System.Threading.Thread.Sleep(10);
		}
	}
}
